#include "PDBManager.h"
#include "glUtil.h"
#include "GLFont.h"

// Responsible for creation and maintenance of data needed to render all visualizations.
// Currently renderer types called by name.  When called, will check if data creation is necessary,
// and then do so, if needed, and then render.

// Also maintains global rendering stuff, at the moment.  May move elsewhere later.

#define SUB_VAN_DER_WAALS_SPHERE	0
#define VAN_DER_WAALS_SPHERE		1

// Manages objects (display lists, textures) only, not temporary state.
// Mostly here so easy to clear everything together.
class ContextData {
public:
	wxGLContext *wxglContext;
	mglMesh *MGL_SPHERE_LISTS[2][26*27];
	mglMesh *MGL_CYL_MESH;
	GLFont *font;

	// Clears all data (except the context itself) without destroying it.
	// For initialization and after destroying data.
	void Clear();

	// Safe to call regardless of where initialized or not.
	// Not guaranteed to set current context.
	void Init(wxGLCanvas *canvas);

	// Destroys data if it exists.  Does not destroy context,
	// just everything else.
	// Guaranteed to set current context.
	void CleanupSharedData(wxGLCanvas *canvas);

	ContextData();

	void Destroy(wxGLCanvas *canvas);

	void DrawSphere(int type, int id, Color c);
};

extern ContextData context;


// Per-residue display information.
// cartoonInitialized is needed to distinguish
// between uninitialized meshes, and cases where
// there is actually no mesh.
struct ResidueRenderData {
	mglMesh *cartoon;
};

// Information needed to draw a connection.  Correspond
// directly to ConnectionInfo array.
struct ConnectionRenderData {
	mglMatrix cylMatrix;
};

struct ChainRenderData {
	ResidueRenderData *residues;
	ConnectionRenderData *connections;

	// Much simpler to just create whole mesh at once, if needed.
	// As need to process current point and 2 points in either direction
	// for splines.
	unsigned int cartoonInitialized:1;

	// Only used for cleanup.
	int numResidues;
	// Not really needed, at the moment.
	int numConnections;
};

struct RenderData {
	PDBManager *pdbManager;
	int refs;
	// Currently don't keep track of models.
	// May remove models entirely at some point.
	// Only used for cleanup, as redundant elsewhere.
	int numChains;
	ChainRenderData chains[1];

	inline void AddRef() {
		refs++;
	}
	void Release();

	void DrawBallAndStick(int chain, int residue, unsigned int flags, Color color);
	void DrawSpaceFill(int chain, int residue, unsigned int flags, Color color);
	void DrawCartoon(int chain, int residue, Color color);

	// Called when changing config to allow display options to be updated.
	// Context must be set before calling.
	// Can't just use a Reinitialize() function because windows may share
	// RenderData.
	void Uninitialize();

	// Only has to be called after uninitializing.  Does not require context
	// be set to call.
	void Initialize();
};

RenderData *CreateRenderData(PDBManager *pdbManager);
